package org.epam.szhuk.greenway.util;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Locale;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.provider.MediaStore.Video;
import android.util.Log;
import android.widget.Toast;

public class FileProcessor {
	private static String TAG="FileProcessor";
	public static void sendFileTo(String path, Context context) {	
	    ContentValues content = new ContentValues(4);
	    content.put(Video.VideoColumns.TITLE, "Recorded video");
	    content.put(Video.VideoColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
	    content.put(Video.Media.MIME_TYPE, "video/mp4");
	    content.put(MediaStore.Video.Media.DATA, path);
	    ContentResolver resolver = context.getContentResolver();
	    Uri uri = resolver.insert(getVideoContentUriForPath(path),  content);
	    Intent intent = new Intent(Intent.ACTION_SEND);
	    intent.setType("video/*");
	    intent.putExtra(Intent.EXTRA_STREAM, uri);
	    context.startActivity(Intent.createChooser(intent, "Share using"));
	}
	
	public static Uri getVideoContentUriForPath(String path) {
		return path.startsWith(Environment.getExternalStorageDirectory()
				.getPath()) ? MediaStore.Video.Media.EXTERNAL_CONTENT_URI
				: MediaStore.Video.Media.INTERNAL_CONTENT_URI;
	}

    public static long getFilenameMsTime(String path) throws Exception{
       int slashIndex=path.lastIndexOf("/")+1;
       String unformattedDateAndTime;
       if(slashIndex>0)
    	   unformattedDateAndTime = path.substring(slashIndex,path.lastIndexOf("."));
       else
    	   unformattedDateAndTime = path.substring(0,path.lastIndexOf("."));
       SimpleDateFormat sdfOld = new SimpleDateFormat(Preferences.DATE_SAVE_MEDIAFILE_FORMAT);
       Date date = sdfOld.parse(unformattedDateAndTime);   
	   return date.getTime();
	}

/*    public static String getStoredCoordFilepath(String videoFilePath) throws Exception{
    	int filenameStart=videoFilePath.lastIndexOf(File.separator)+1;
		int filenameEnd=videoFilePath.lastIndexOf(".");
		String videoFileName=new String(videoFilePath.substring(filenameStart, filenameEnd));
		String appFolder=videoFilePath.substring(0, videoFilePath.lastIndexOf(File.separator));
		String result=appFolder+ File.separator +Preferences.FOLDER_TRACKS+File.separator+videoFileName+".txt";		
 	   	return result;
 	} */
    
	 public static String getFilenameFormattedDate(String path) throws Exception{
		   String formattedDateAndTime="";
           int slashIndex=path.lastIndexOf("/")+1;
           String unformattedDateAndTime;
           if(slashIndex>0){
        	   unformattedDateAndTime = path.substring(slashIndex,path.lastIndexOf("."));
           }
           else{
        	   unformattedDateAndTime = path.substring(0,path.lastIndexOf("."));
           }
           SimpleDateFormat sdfOld = new SimpleDateFormat(Preferences.DATE_SAVE_MEDIAFILE_FORMAT);
           Date date = sdfOld.parse(unformattedDateAndTime);   
           SimpleDateFormat sdf = new SimpleDateFormat(Preferences.DATE_TITLE_PLAYVIDEO_FORMAT, java.util.Locale.getDefault());
           formattedDateAndTime = sdf.format(date);

           return formattedDateAndTime;
	   }
		/**
		 * Removes thumb image with the same name as path parameter, stored in the thumbFolder 
		 *
		 * @return true if removed successful
		 */
		public static boolean removeThumbImage(String path, String thumbFolder){
			String dirPath=path.substring(0, path.lastIndexOf(File.separator));
			String thumbFileName=path.substring(path.lastIndexOf(File.separator)+1,path.lastIndexOf('.'))+".jpg";
			File file = new File(dirPath+File.separator+thumbFolder+File.separator+thumbFileName);
			boolean result=file.delete();
			return result;
		}
		
		/**
		 * Removes txt track file with the same name as path parameter, stored in the thracksFolder 
		 *
		 * @param videoFilePath path to ROOT application folder (where recorded videos are stored)
		 * @return true if removed successful
		 */
		public static boolean removeTrackFile(String videoFilePath, String trackFolder){
			String dirPath=videoFilePath.substring(0, videoFilePath.lastIndexOf(File.separator));
			String trackFileName=videoFilePath.substring(videoFilePath.lastIndexOf(File.separator)+1,videoFilePath.lastIndexOf('.'))+".txt";
			File file = new File(dirPath+File.separator+trackFolder+File.separator+trackFileName);
			boolean result=file.delete();
			return result;
		}		

		/**
		 * Removes file directly if exists 
		 *
		 * @param filePath path to ROOT application folder (where recorded videos are stored)
		 * @return true if removed successful
		 */
		public static boolean removeFile(String filePath){
			File file = new File(filePath);
			return removeFile(file);
		}
		
		/**
		 * Removes file directly if exists 
		 *
		 * @param filePath path to ROOT application folder (where recorded videos are stored)
		 * @return true if removed successful
		 */
		public static boolean removeFile(File file){
			boolean result=false;
			if(file!=null){
				result=file.delete();
			}
			else{
				Log.e(TAG, "Null received as a parameter for removeFile");
			}
			return result;
		}
		
		/**
		 * Return the size of a directory in bytes
		 */
		public static long dirSize(File dir) {
		    if (dir.exists()) {
		        long result = 0;
		        File[] fileList = dir.listFiles();
		        for(int i = 0; i < fileList.length; i++) {
		            // Recursive call if it's a directory
		            if(fileList[i].isDirectory()) {
		                result += dirSize(fileList [i]);
		            } else {
		                // Sum the file size in bytes
		                result += fileList[i].length();
		            }
		        }
		        return result; // return the file size
		    }
		    return 0;
		}
		
	/**
	 * Deletes the oldest *.mp4 file in folder,
	 * the age of file being calculated by its name ("YYYY_MM_DD" etc)
	 * 
	 * @param folderPath
	 * @return true id delete successful
	 */
	public static boolean delOldestMP4File(String dirPath){
		File folderDirPath = new File(dirPath);
		File[] files = folderDirPath.listFiles();
		Date minDate=new Date();
		minDate.setYear(minDate.getYear()+1);// unreachable year to search min
		File selectedFile=null;
		if(files!=null){
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				SimpleDateFormat sdf = new SimpleDateFormat(Preferences.DATE_SAVE_MEDIAFILE_FORMAT);
				if ((file.canRead())&&(!file.isDirectory()) && (file.getName().endsWith("mp4"))) { 
   					  // adding to list only files that could be accessed by our app
			          String unformattedDateAndTime = file.getName().substring(0,file.getName().lastIndexOf("."));
			          try{
				          Date fileDate = sdf.parse(unformattedDateAndTime);
				          if(fileDate.compareTo(minDate)<=0){
				        		minDate=fileDate;
				        		selectedFile=file;
				          }
			          }
			          catch(ParseException e){
			        	  Log.e(TAG, "ParceException with "+Preferences.DATE_SAVE_MEDIAFILE_FORMAT+" data pattern: "+file.getAbsolutePath(), e);
			          }
			      }
			}
		}
		if(selectedFile!=null){
			if(!removeThumbImage(selectedFile.getAbsolutePath(),Preferences.FOLDER_THUMBS)){
				Log.i(TAG, "Can't delete thumb of the file "+selectedFile.getAbsolutePath());
			}
			//remove track speed data is now separate function
			/*if(!removeTrackFile(selectedFile.getAbsolutePath(),Preferences.FOLDER_TRACKS)){
				Log.i(TAG, "Can't delete track file of the file "+selectedFile.getAbsolutePath());
			}*/
			return selectedFile.delete();
		}
		else{
			return false;
		}
	}

	/**
	 * Deletes the oldest *.mp4 files in folder, to meke free inputed memory size.
	 * the age of files being calculated by its name ("YYYY_MM_DD" etc)
	 * 
	 * If not available for videos folder free space is less then spaceToMakeFree - just clear all folder
	 * 
	 * @param folderPath
	 * @param spaceToMakeFree size in bytes to make it free
	 * @return true id delete successful
	 */
	public static boolean delOldestMP4FileForFreeSpace(String dirPath, long spaceToMakeFree){
		File folderDirPath = new File(dirPath);
		File[] files = folderDirPath.listFiles();
		Date minDate=new Date();
		minDate.setYear(minDate.getYear()+1);// unreachable year to search min
		long clearedSpace=0;
		if(files!=null){
			Arrays.sort(files);
			
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if ((file.canRead())&&(!file.isDirectory()) && (file.getName().endsWith("mp4"))) { 
					if(!removeThumbImage(file.getAbsolutePath(),Preferences.FOLDER_THUMBS)){
						Log.i(TAG, "Can't delete thumb of the file "+file.getAbsolutePath());
					}
					long tempFileSize=file.length();
					if(file.delete()){
						clearedSpace+=tempFileSize;
						Log.i(TAG, "File deleted to get free space: "+file.getAbsolutePath());
					}
					if(clearedSpace>=spaceToMakeFree){
						break;//break loop of file deleting
					}
				}
			}
		}
		if(clearedSpace>0){
			return true;
		}
		else{
			return false;
		}
	}	
	
	/**
	 * Return free ext storage space in BYTES
	 */
	public static long getFreeExtStorageSpace(){
		String extStorageState = Environment.getExternalStorageState();
		if (extStorageState.equals(Environment.MEDIA_MOUNTED)){
			File path = Environment.getExternalStorageDirectory();
			
			StatFs stat = new StatFs(path.getPath());
			long blockSize = stat.getBlockSize();
			long availableBlocks = stat.getAvailableBlocks();
			 
			return availableBlocks * blockSize; 			
		}
		else{
			return -1L;
		}
	}
	
	public static boolean deleteAllVideos(String dirPath){
		File folderDirPath = new File(dirPath);
		File[] files = folderDirPath.listFiles();
		boolean success=true;
		if(files!=null){
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if ((file.canRead())&&(!file.isDirectory()) && (file.getName().endsWith("mp4"))) { 
						if(!removeThumbImage(file.getAbsolutePath(),Preferences.FOLDER_THUMBS)){
							Log.i(TAG, "Can't delete thumb of the file "+file.getAbsolutePath());
						}
						//remove track is now separate function
						/*if(!removeTrackFile(file.getAbsolutePath(),Preferences.FOLDER_TRACKS)){
							Log.i(TAG, "Can't delete track file of the file "+file.getAbsolutePath());
						}*/
				        if(!file.delete())
				        	success=false;
			      }
			}
		}
		return success;
	}
	
	public static boolean deleteAllTracks(String dirPath){
		File folderDirPath = new File(dirPath);
		File[] files = folderDirPath.listFiles();
		boolean success=true;
		if(files!=null){
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if ((file.canRead())&&(!file.isDirectory()) && (file.getName().endsWith("txt"))) { 					
				        if(!file.delete()){
				        	success=false;
				        }
			      }
			}
		}
		return success;
	}	
	
	/**
	 * Removes old files one-by-one or makes command to stop recording if it was set in ActionOnFullFolder prefs
	 *
	 * @param recordMaxSize
	 * @param context
	 * @param prefs
	 * @return true if success
	 */
  /*  public static boolean actionWithOldestFiles(Context context,  Preferences prefs){
    	int recRestartCounter=0; //counter to check if smth wrong with loop of files going to be removed
    	Log.w(TAG, "Current max available space in for videos bytes ="+prefs.getRecordMaxSize());
    	while((prefs.getRecordMaxSize()==Preferences.REC_MAX_SIZE_FOLDER_MAXSIZE_REACHED)||(prefs.getRecordMaxSize()==Preferences.REC_MAX_SIZE_NOMORE_FREE_SPACE)){
	    	if(prefs.getRecordMaxSize()==Preferences.REC_MAX_SIZE_NOMORE_FREE_SPACE){
	        	Log.w(TAG,"Not enough free space on the external storage");
	        	//myToast(context,"Not enough free space on the external storage"); 
	        }
	        else{//recordMaxSize==REC_MAX_SIZE_FOLDER_MAXSIZE_REACHED
	        	Log.w(TAG,"Max folder size reached");
	    		//myToast(context,"Max folder size reached");
	        }
	    	if(prefs.getActionOnFullFolder()==Preferences.IF_NO_FREE_DELETE_OLDEST_FILE){
	    		Log.w(TAG,"Next action: delete oldest file");
	    		myToast(context, context.getResources().getString(R.string.next_action_delete_oldest));
	    		String folderPath=Environment.getExternalStorageDirectory() +  File.separator +prefs.getAppFilesFolder();
	    		boolean oldestFileDeletedSuccess
	    			= FileProcessor.delOldestMP4FileForFreeSpace(folderPath, prefs.getMaxOneFileSizeMb()*1024*1024);
	    		if(!oldestFileDeletedSuccess){
	    			Log.e(TAG,"Can't delete the oldest file in the folder to get free space for the app folder");	
	    			myToast(context, context.getResources().getString(R.string.cant_delete_oldest_file));
	    			return false;
	    		}
	    		else{
    				Log.w(TAG,"Oldest file deleted, move to the begin of loop");
    				recRestartCounter++;
    				if(recRestartCounter>100){
    					break; //exits from while(...) loop
    				}
    				else{
    					continue; //move to next while(...) step
    				}
	    		}
	       	}
	    	else if(prefs.getActionOnFullFolder()==Preferences.IF_NO_FREE_STOP_RECORDING){
	    		Log.w(TAG,"Next action: stop recording");
	    		myToast(context,context.getResources().getString(R.string.next_action_stop_rec));
	    		return false;
	       	}
    	}//end while(..)
    	
    	if(recRestartCounter<100){
    		return true;//everything is OK if this code reached
    	}
    	else{
			Log.e(TAG,"Error in the delete oldest file loop");	
			myToast(context,"Error in the delete oldest file loop");
			return false;
    	}
    }
*/
    private static void myToast(Context context, String text){
    	Toast.makeText(context, text, Toast.LENGTH_LONG).show();
    }
}
